/*
 * File:        duplicateList.h
 * Authors:     Shaan Mulchandani (ee122-bv) and Jonathan Kotker (ee122-bw)
 * Description: This header file defines a history list, keeping track
 *              of messages that have been sent.
 */

#ifndef _DUPLICATELIST_H
#define	_DUPLICATELIST_H

#include "constants.h"
#include "duplicate.h"

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    /* Head of the linked list. */
    duplicate* head;

    /* Tail of the linked list. */
    duplicate* tail;

    /* Number of entries in the linked list. */
    int numDuplicates;

} duplicateList;

/*
 * Checks to see if a duplicate is in the duplicate list.
 * If it is, returns the corresponding entry in the history list.
 */
duplicate* existsInList(duplicateList* list, duplicate* newDuplicateInfo) {
    if (list == NULL) return NULL;

    int found = 0;
    duplicate* result = list->head;

    while (result && !found) {
        if ((result->id == newDuplicateInfo->id) &&
                ((memcmp(&result->server_ip_add,
                &newDuplicateInfo->server_ip_add,
                sizeof (newDuplicateInfo->server_ip_add))) == 0))
            found = 1;
        else
            result = result->next;
    }

    return result;
};

/*
 * Initializes the history list.
 */
void initDuplicateList(duplicateList* list) {
    list->head = NULL;
    list->tail = NULL;
    list->numDuplicates = 0;
};

/*
 * Deallocates the dynamic memory allocated to this list.
 */
void clearDuplicateList(duplicateList* list) {
    duplicate* currNode;
    duplicate* nextNode;

    currNode = list->head;

    while (currNode != NULL) {
        nextNode = currNode->next;
        free(currNode);
        currNode = nextNode;
    }
};

/*
 * Adds the new request/response information to the history list.
 */
void addDuplicateInfo(duplicateList* list, duplicate* newDuplicateInfo) {
    if (list == NULL) return;

    newDuplicateInfo->next = NULL;

    if (list->head == NULL) {
        list->head = newDuplicateInfo;
        list->tail = newDuplicateInfo;
        newDuplicateInfo->prev = NULL;
        list->numDuplicates++;
    } else {
        if (list->numDuplicates == 50) {
            list->head = list->head->next;

            duplicate* oldHead = list->head->prev;
            oldHead->next = NULL;
            list->head->prev = NULL;
            free(oldHead);

            list->numDuplicates--;
        }

        newDuplicateInfo->prev = list->tail;
        list->tail->next = newDuplicateInfo;
        list->tail = newDuplicateInfo;
        list->numDuplicates++;
    }
};

#endif	/* _DUPLICATELIST_H */
